/*
  Time-stamp: <2009-11-12 13:23:29 xinhaoyuan>

  File: keyboard.c

  This file provide a simple driver for keyboard. The driver simply
  grab the keyboard interrupt. Then get the data and put the data into
  the kernel pipe.
  
*/

#define _EKOS_KERNEL_C_

#include <kernel/kernel.h>
#include <kernel/console.h>

KERNEL_EXPORT struct kpipe_t keyboard_pipe __attribute__ ((aligned (PAGE_SIZE)));

/*
  The processor for keyboard interrupt
  Simply push the scan code into the queue
*/

static int
keyboard_intr(struct trapframe_t* tf)
{
	 uint8_t data;
     if ((inb(KBSTATP) & KBS_DIB) == 0)
	 	  return;
     data = inb(KBDATAP);
	 /* grab ESC Key and then turn into system monitor */
	 if (data == 1)
		  monitor(tf);
	 else
	 {
		  /*
			since the interrupt is disabled in IRQ processing and the
			syscall read_irq_pipe disable the IRQ, we can roughly write
			this
		  */
		  kpipe_write_unsafe(&keyboard_pipe, &data, 1);
		  semaphore_notify(irq_semaphores + 1);
	 }

	 return 0;
}

KERNEL_EXPORT int
keyboard_init(void)
{
	 if ((uintptr_t)(&keyboard_pipe) & (PAGE_SIZE - 1)) {
		  return 1;
	 }

	 int result;
	 if ((result = kpipe_open(&keyboard_pipe))) return result;

	 register_irq_pipe(1, &keyboard_pipe);
	 register_irq_handler(1, &keyboard_intr);

	 enable_irq_line(1);

	 cprintf("KEYBOARD DRIVER DONE\n");

	 return 0;
}
